/*

 * Copyright (C) 2021 Huawei Device Co., Ltd.

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */
package zaizai.com;


import com.ajguan.ResourceTable;
import com.aries.ui.view.tab.IndicatorStyle;
import com.aries.ui.view.tab.TextBold;
import com.aries.ui.view.tab.delegate.TabCommonDelegate;
import com.aries.ui.view.tab.listener.CustomTabEntity;
import com.aries.ui.view.tab.listener.ITabLayout;
import com.aries.ui.view.tab.listener.OnTabSelectListener;
import com.aries.ui.view.tab.utils.AttrUtils;
import com.aries.ui.view.tab.utils.FragmentChangeManager;
import com.aries.ui.view.tab.utils.UnreadMsgUtils;
import com.aries.ui.view.tab.widget.MsgView;
import ohos.aafwk.ability.fraction.Fraction;
import ohos.aafwk.ability.fraction.FractionManager;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.Path;
import ohos.agp.text.Font;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.utils.Rect;
import ohos.app.Context;
import ohos.global.resource.Element;
import ohos.global.resource.NotExistException;
import ohos.global.resource.WrongTypeException;
import ohos.utils.PlainArray;

import java.io.IOException;
import java.util.ArrayList;

/**
 * @Author: AriesHoo on 2018/11/30 9:48
 * @E-Mail: AriesHoo@126.com
 * @Function: 没有继承HorizontalScrollView不能滑动, 对于ViewPager无依赖
 * 与原库不一致地方: 修改原库text 为{@link zaizai.com.slice.RippleView}
 * 宽高调整为MATCH_PARENT
 */
public class CommonTabLayout extends StackLayout
        implements ITabLayout, AnimatorValue.ValueUpdateListener, Component.DrawTask {
    private TabCommonDelegate mDelegate;
    private Context mContext;
    private ArrayList<CustomTabEntity> mTabEntity = new ArrayList<>();
    private DirectionalLayout mTabsContainer;
    private int mCurrentSelected = -1;
    private int mCurrentTab;
    private int mLastTab;
    private int mTabCount;
    /**
     * 用于绘制显示器
     */
    private Rect mIndicatorRect = new Rect();
    private ShapeElement mIndicatorDrawable = new ShapeElement();
    private Paint mRectPaint = new Paint();
    private Paint mDividerPaint = new Paint();
    private Paint mTrianglePaint = new Paint();
    private Path mTrianglePath = new Path();
    private int mHeight;

    private OnTabSelectListener mListener;
    private boolean mIsFirstDraw = true;


    private final AnimatorValue mValueAnimator;

    private FragmentChangeManager mFragmentChangeManager;


    public CommonTabLayout(Context context) {
        this(context, null);
    }

    public CommonTabLayout(Context context, AttrSet attrs) {
        super(context, attrs);
        mDelegate = new TabCommonDelegate(this, attrs, this);
        this.mContext = context;
        mTabsContainer = new DirectionalLayout(context);
        DirectionalLayout.LayoutConfig layoutConfig;
        // get layout_height
        String height = attrs == null ? "" : attrs.getAttr("height").get().getStringValue();
        if (height.equals(ComponentContainer.LayoutConfig.MATCH_PARENT + "")) {
            layoutConfig = new DirectionalLayout.LayoutConfig(LayoutConfig.MATCH_PARENT,
                    LayoutConfig.MATCH_PARENT);
        } else if (height.equals(ComponentContainer.LayoutConfig.MATCH_CONTENT + "")) {
            layoutConfig = new DirectionalLayout.LayoutConfig(LayoutConfig.MATCH_PARENT,
                    LayoutConfig.MATCH_CONTENT);
        } else {
            layoutConfig = new DirectionalLayout.LayoutConfig(LayoutConfig.MATCH_PARENT,
                    LayoutConfig.MATCH_PARENT);
            mHeight = AttrUtils.getDimensionFromAttr(attrs, "height", ComponentContainer.LayoutConfig.MATCH_CONTENT);
        }
        mTabsContainer.setOrientation(DirectionalLayout.HORIZONTAL);
        mTabsContainer.setLayoutConfig(layoutConfig);
        addComponent(mTabsContainer);
        mValueAnimator = new AnimatorValue();
        mValueAnimator.setValueUpdateListener(this);
        addDrawTask(this, DrawTask.BETWEEN_BACKGROUND_AND_CONTENT);
    }

    /**
     * 获取代理属性
     *
     * @return TabCommonDelegate
     */
    public TabCommonDelegate getDelegate() {
        return mDelegate;
    }

    /**
     * 设置tab 数据
     *
     * @param tabEntity CustomTabEntity集合
     * @return CommonTabLayout
     * @throws NullPointerException TabEntity can not be NULL or EMPTY
     */
    public CommonTabLayout setTabData(ArrayList<CustomTabEntity> tabEntity) {
        if (tabEntity == null || tabEntity.size() == 0) {
            throw new NullPointerException("TabEntity can not be NULL or EMPTY !");
        }

        this.mTabEntity.clear();
        this.mTabEntity.addAll(tabEntity);
        this.mTabCount = mTabEntity.size();
        notifyDataSetChanged();
        return this;
    }

    /**
     * 关联数据支持同时切换fragments
     *
     * @param tabEntity       tabEntity
     * @param manager         manager
     * @param containerViewId containerViewId
     * @param fragments       fragments
     * @return CommonTabLayout
     */
    public CommonTabLayout setTabData(ArrayList<CustomTabEntity> tabEntity,
                                      FractionManager manager,
                                      int containerViewId,
                                      ArrayList<Fraction> fragments) {
        mFragmentChangeManager = new FragmentChangeManager(manager, containerViewId, fragments);
        return setTabData(tabEntity);
    }

    /**
     * 更新数据
     */
    public void notifyDataSetChanged() {
        mTabsContainer.removeAllComponents();
        Component tabView;
        for (int i = 0; i < mTabCount; i++) {
            if (getDelegate().getIconGravity() == LayoutAlignment.LEFT) {
                tabView = LayoutScatter.getInstance(mContext).parse(ResourceTable.Layout_layout_tab_left, null, false);
            } else if (getDelegate().getIconGravity() == LayoutAlignment.RIGHT) {
                tabView = LayoutScatter.getInstance(mContext)
                        .parse(ResourceTable.Layout_layout_tab_right, null, false);
            } else if (getDelegate().getIconGravity() == LayoutAlignment.BOTTOM) {
                tabView = LayoutScatter.getInstance(mContext)
                        .parse(ResourceTable.Layout_layout_tab_bottom, null, false);
            } else {
                tabView = LayoutScatter.getInstance(mContext).parse(ResourceTable.Layout_layout_tab_top, null, false);
            }

            tabView.setTag(i);
            addTab(i, tabView);
        }
        updateTabStyles();
    }

    /**
     * 创建并添加tab
     *
     * @param position position
     * @param tabView  tabView
     */
    private void addTab(final int position, final Component tabView) {
        Text tvTabTitle = (Text) tabView.findComponentById(ResourceTable.Id_tv_tab_title);
        tvTabTitle.setText(mTabEntity.get(position).getTabTitle());
        Image ivTabIcon = (Image) tabView.findComponentById(ResourceTable.Id_iv_tab_icon);
        ivTabIcon.setPixelMap(mTabEntity.get(position).getTabUnselectedIcon());
        tvTabTitle.setClickedListener(new ClickedListener() {
            @Override
            public void onClick(Component component) {
                int position = (Integer) tabView.getTag();
                setCurrentTab(position);
            }
        });

        /** 每一个Tab的布局参数 */
        DirectionalLayout.LayoutConfig lpTab = getDelegate().isTabSpaceEqual() ?
                new DirectionalLayout.LayoutConfig(DirectionalLayout.LayoutConfig.MATCH_PARENT,
                        DirectionalLayout.LayoutConfig.MATCH_PARENT, LayoutAlignment.CENTER, 1.0f) :
                new DirectionalLayout.LayoutConfig(DirectionalLayout.LayoutConfig.MATCH_CONTENT,
                        DirectionalLayout.LayoutConfig.MATCH_PARENT);
        if (getDelegate().getTabWidth() > 0) {
            lpTab = new DirectionalLayout.LayoutConfig(getDelegate().getTabWidth(),
                    DirectionalLayout.LayoutConfig.MATCH_PARENT);
        }
        mTabsContainer.addComponent(tabView, position, lpTab);
    }

    @Override
    public void updateTabStyles() {
        for (int i = 0; i < mTabCount; i++) {
            Component tabView = mTabsContainer.getComponentAt(i);
            tabView.setPadding(getDelegate().getTabPadding(), 0, getDelegate().getTabPadding(), 0);
            updateTabTitle(i, tabView);
            updateTabIcon(i, tabView);
        }
    }

    /**
     * 更新tab的title
     *
     * @param index   角标
     * @param tabView 根布局
     */
    private void updateTabTitle(int index, Component tabView) {
        Text tvTabTitle = (Text) tabView.findComponentById(ResourceTable.Id_tv_tab_title);
        tvTabTitle.setTextColor(new Color(index == mCurrentTab ?
                getDelegate().getTextSelectColor() : getDelegate().getTextUnSelectColor()));
        tvTabTitle.setTextSize((int) (mCurrentTab == index ?
                getDelegate().getTextSelectSize() : getDelegate().getTextSize()), getDelegate().getTextSizeUnit());
        if (getDelegate().isTextAllCaps()) {
            tvTabTitle.setText(tvTabTitle.getText().toString().toUpperCase());
        }
        if (getDelegate().getTextBold() == TextBold.BOTH) {
            tvTabTitle.setFont(Font.DEFAULT_BOLD);
        } else if (getDelegate().getTextBold() == TextBold.SELECT) {
            //增加-以修正原库第一次选中粗体不生效问题
            tvTabTitle.setFont(mCurrentTab == index ? Font.DEFAULT_BOLD : Font.DEFAULT);
        } else {
            tvTabTitle.setFont(Font.DEFAULT_BOLD);
        }
    }


    /**
     * 更新tab的icon
     *
     * @param index   角标
     * @param tabView 根布局
     */
    private void updateTabIcon(int index, Component tabView) {
        Image ivTabIcon = (Image) tabView.findComponentById(ResourceTable.Id_iv_tab_icon);
        if (getDelegate().isIconVisible()) {
            ivTabIcon.setVisibility(VISIBLE);
            CustomTabEntity tabEntity = mTabEntity.get(index);
            ivTabIcon.setPixelMap(index == mCurrentTab ?
                    tabEntity.getTabSelectedIcon() : tabEntity.getTabUnselectedIcon());
            DirectionalLayout.LayoutConfig lp = new DirectionalLayout.LayoutConfig(
                    getDelegate().getIconWidth() <= 0 ?
                            DirectionalLayout.LayoutConfig.MATCH_CONTENT : getDelegate().getIconWidth(),
                    getDelegate().getIconHeight() <= 0 ?
                            DirectionalLayout.LayoutConfig.MATCH_CONTENT : getDelegate().getIconHeight());
            if (getDelegate().getIconGravity() == LayoutAlignment.LEFT
                    || getDelegate().getIconGravity() == LayoutAlignment.RIGHT) {
                lp.setMarginRight(getDelegate().getIconMargin());
            } else {
                lp.setMarginBottom(getDelegate().getIconMargin());
            }
            ivTabIcon.setLayoutConfig(lp);
        } else {
            ivTabIcon.setVisibility(HIDE);
        }
    }

    /**
     * 更新position的icon
     *
     * @param position 角标
     */
    private void updateTabSelection(int position) {
        for (int i = 0; i < mTabCount; ++i) {
            Component tabView = mTabsContainer.getComponentAt(i);
            final boolean isSelect = i == position;
            Text tab_title = (Text) tabView.findComponentById(ResourceTable.Id_tv_tab_title);
            setData(i, tabView, isSelect, tab_title);
        }
    }


    /**
     * 设置数据
     *
     * @param position 角标
     * @param tabView  跟布局
     * @param isSelect 是否选择
     * @param tabTitle title
     */
    private void setData(int position, Component tabView, boolean isSelect, Text tabTitle) {
        if (tabTitle != null) {
            tabTitle.setTextColor(new Color(isSelect ?
                    getDelegate().getTextSelectColor() : getDelegate().getTextUnSelectColor()));
            tabTitle.setTextSize((int) (mCurrentTab == position ?
                    getDelegate().getTextSelectSize() : getDelegate().getTextSize()), getDelegate().getTextSizeUnit());
            Image ivTabIcon = (Image) tabView.findComponentById(ResourceTable.Id_iv_tab_icon);
            CustomTabEntity tabEntity = mTabEntity.get(position);
            ivTabIcon.setPixelMap(isSelect ? tabEntity.getTabSelectedIcon() : tabEntity.getTabUnselectedIcon());
            if (getDelegate().getTextBold() == TextBold.SELECT) {
                tabTitle.setFont(isSelect ? Font.DEFAULT_BOLD : Font.DEFAULT);
            }
        }
    }

    private void calcOffset() {
        final Component currentTabView = mTabsContainer.getComponentAt(this.mCurrentTab);
        if (currentTabView == null) {
            return;
        }
        mCurrentP.left = currentTabView.getLeft();
        mCurrentP.right = currentTabView.getRight();

        final Component lastTabView = mTabsContainer.getComponentAt(this.mLastTab);
        mLastP.left = lastTabView.getLeft();
        mLastP.right = lastTabView.getRight();
        if (mLastP.left == mCurrentP.left && mLastP.right == mCurrentP.right) {
            invalidate();
        } else {
            if (getDelegate().getIndicatorAnimDuration() < 0) {
                getDelegate().setIndicatorAnimDuration(getDelegate().isIndicatorBounceEnable() ? 500 : 250);
            }
            if (getDelegate().isIndicatorBounceEnable()) {
                mValueAnimator.setCurveType(Animator.CurveType.ANTICIPATE_OVERSHOOT);
            }
            mValueAnimator.setDuration(getDelegate().getIndicatorAnimDuration());
            mValueAnimator.start();
        }
    }

    private void calcIndicatorRect() {
        Component currentTabView = mTabsContainer.getComponentAt(this.mCurrentTab);
        float left = currentTabView.getLeft();
        float right = currentTabView.getRight();

        mIndicatorRect.left = (int) left;
        mIndicatorRect.right = (int) right;

        // indicatorWidth小于0时,原jpardogo's PagerSlidingTabStrip
        if (getDelegate().getIndicatorWidth() < 0) {

        } else { // indicatorWidth大于0时,圆角矩形以及三角形
            float indicatorLeft = currentTabView.getLeft()
                    + (currentTabView.getWidth()
                    - getDelegate().getIndicatorWidth()) / 2;
            mIndicatorRect.left = (int) indicatorLeft;
            mIndicatorRect.right = (int) (mIndicatorRect.left + getDelegate().getIndicatorWidth());
        }
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        // isInEditMode
        if (mTabCount <= 0) {
            return;
        }
        int height = getHeight();
        int paddingLeft = getPaddingLeft();
        // draw divider
        drawDivider(canvas, height, paddingLeft);
        // draw underline
        drawaUnderline(canvas, height, paddingLeft);
        // draw indicator line
        if (getDelegate().isIndicatorAnimEnable()) {
            if (mIsFirstDraw) {
                mIsFirstDraw = false;
                calcIndicatorRect();
            }
        } else {
            calcIndicatorRect();
        }
        if (getDelegate().getIndicatorStyle() == IndicatorStyle.TRIANGLE) {
            drawTriangle(canvas, height, paddingLeft);
        } else if (getDelegate().getIndicatorStyle() == IndicatorStyle.BLOCK) {
            drawBlock(canvas, height, paddingLeft);
        } else {
            drawOthers(canvas, height, paddingLeft);
        }
    }

    private void drawOthers(Canvas canvas, int height, int paddingLeft) {
        if (getDelegate().getIndicatorHeight() > 0) {
            mIndicatorDrawable.setRgbColor(RgbColor.fromArgbInt(getDelegate().getIndicatorColor()));
            if (getDelegate().getIndicatorGravity() == LayoutAlignment.BOTTOM) {
                mIndicatorDrawable.setBounds(paddingLeft + getDelegate().getIndicatorMarginLeft() + mIndicatorRect.left,
                        height - getDelegate().getIndicatorHeight() - getDelegate().getIndicatorMarginBottom(),
                        paddingLeft + mIndicatorRect.right - getDelegate().getIndicatorMarginRight(),
                        height - getDelegate().getIndicatorMarginBottom());
            } else {
                mIndicatorDrawable.setBounds(paddingLeft
                                + (int) getDelegate().getIndicatorMarginLeft()
                                + mIndicatorRect.left,
                        (int) getDelegate().getIndicatorMarginTop(),
                        paddingLeft + mIndicatorRect.right - (int) getDelegate().getIndicatorMarginRight(),
                        (int) getDelegate().getIndicatorHeight() + (int) getDelegate().getIndicatorMarginTop());
            }
            mIndicatorDrawable.setCornerRadius(getDelegate().getIndicatorCornerRadius());
            mIndicatorDrawable.drawToCanvas(canvas);
        }
    }

    private void drawBlock(Canvas canvas, int height, int paddingLeft) {
        if (getDelegate().getIndicatorHeight() < 0) {
            getDelegate().setIndicatorHeight(height
                    - getDelegate().getIndicatorMarginTop()
                    - getDelegate().getIndicatorMarginBottom());
        }
        if (getDelegate().getIndicatorHeight() > 0) {
            if (getDelegate().getIndicatorCornerRadius() < 0
                    || getDelegate().getIndicatorCornerRadius() > getDelegate().getIndicatorHeight() / (double) 2) {
                getDelegate().setIndicatorCornerRadius((float) (getDelegate().getIndicatorHeight() / (double) 2));
            }

            mIndicatorDrawable.setRgbColor(RgbColor.fromArgbInt(getDelegate().getIndicatorColor()));
            mIndicatorDrawable.setBounds(paddingLeft + getDelegate().getIndicatorMarginLeft() + mIndicatorRect.left,
                    getDelegate().getIndicatorMarginTop(),
                    (paddingLeft + mIndicatorRect.right - getDelegate().getIndicatorMarginRight()),
                    (int) (getDelegate().getIndicatorMarginTop() + getDelegate().getIndicatorHeight()));
            mIndicatorDrawable.setCornerRadius(getDelegate().getIndicatorCornerRadius());
            mIndicatorDrawable.drawToCanvas(canvas);
        }
    }

    private void drawTriangle(Canvas canvas, int height, int paddingLeft) {
        if (getDelegate().getIndicatorHeight() > 0) {
            mTrianglePaint.setColor(new Color(getDelegate().getIndicatorColor()));
            mTrianglePath.reset();
            mTrianglePath.moveTo(paddingLeft + mIndicatorRect.left, height);
            mTrianglePath.lineTo(paddingLeft
                    + mIndicatorRect.left / 2
                    + mIndicatorRect.right / 2, height - getDelegate().getIndicatorHeight());
            mTrianglePath.lineTo(paddingLeft + mIndicatorRect.right, height);
            mTrianglePath.close();
            canvas.drawPath(mTrianglePath, mTrianglePaint);
        }
    }

    private void drawaUnderline(Canvas canvas, int height, int paddingLeft) {
        if (getDelegate().getUnderlineHeight() > 0) {
            mRectPaint.setColor(new Color(getDelegate().getUnderlineColor()));
            if (getDelegate().getUnderlineGravity() == LayoutAlignment.BOTTOM) {
                canvas.drawRect(paddingLeft,
                        (float) (height - (double) getDelegate().getUnderlineHeight()),
                        mTabsContainer.getWidth() + paddingLeft, height, mRectPaint);
            } else {
                canvas.drawRect(paddingLeft, 0,
                        mTabsContainer.getWidth() + paddingLeft,
                        getDelegate().getUnderlineHeight(), mRectPaint);
            }
        }
    }

    private void drawDivider(Canvas canvas, int height, int paddingLeft) {
        if (getDelegate().getDividerWidth() > 0) {
            mDividerPaint.setStrokeWidth(getDelegate().getDividerWidth());
            mDividerPaint.setColor(new Color(getDelegate().getDividerColor()));
            for (int i = 0; i < mTabCount - 1; i++) {
                Component tab = mTabsContainer.getComponentAt(i);
                canvas.drawLine(paddingLeft + tab.getRight(),
                        getDelegate().getDividerPadding(),
                        paddingLeft + tab.getRight(),
                        (float) (height - (double) getDelegate().getDividerPadding()),
                        mDividerPaint);
            }
        }
    }

    /**
     * 设置当前选中Tab
     *
     * @param currentTab 选中Tab
     * @return CommonTabLayout
     */
    public CommonTabLayout setCurrentTab(int currentTab) {
        if (mCurrentSelected != currentTab) {
            mLastTab = this.mCurrentTab;
            this.mCurrentTab = currentTab;
            this.mCurrentSelected = currentTab;
            updateTabSelection(currentTab);
            if (getDelegate().isIndicatorAnimEnable()) {
                calcOffset();
            } else {
                invalidate();
            }
            if (mFragmentChangeManager != null) {
                mFragmentChangeManager.setFragments(currentTab);
            }
            if (mListener != null) {
                mListener.onTabSelect(currentTab);
            }
        } else {
            if (mListener != null) {
                mListener.onTabReselect(currentTab);
            }
        }
        return this;
    }

    /**
     * 获取tab 数量
     *
     * @return int
     */
    public int getTabCount() {
        return mTabCount;
    }

    /**
     * 获取当前tab角标
     *
     * @return int
     */
    public int getCurrentTab() {
        return mCurrentTab;
    }

    /**
     * 获取tab的图片
     *
     * @param tab 角标
     * @return Image
     */
    public Image getIconView(int tab) {
        Component tabView = mTabsContainer.getComponentAt(tab);
        Image ivTabIcon = (Image) tabView.findComponentById(ResourceTable.Id_iv_tab_icon);
        return ivTabIcon;
    }

    /**
     * 获取tab的文字标题
     *
     * @param tab 角标
     * @return Text
     */
    public Text getTitleView(int tab) {
        Component tabView = mTabsContainer.getComponentAt(tab);
        return (Text) tabView.findComponentById(ResourceTable.Id_tv_tab_title);
    }

    /**
     * show MsgTipView
     */
    private Paint mTextPaint = new Paint();

    private PlainArray<Boolean> mInitSetMap = new PlainArray<>();

    /**
     * 显示未读消息
     *
     * @param position 显示tab位置
     * @param num      num小于等于0显示红点,num大于0显示数字
     * @return CommonTabLayout
     */
    public CommonTabLayout showMsg(final int position, int num) {
        int tempPosition = position;
        if (tempPosition >= mTabCount) {
            tempPosition = mTabCount - 1;
        }

        Component tabView = mTabsContainer.getComponentAt(tempPosition);
        MsgView tipView = (MsgView) tabView.findComponentById(ResourceTable.Id_rtv_msg_tip);
        if (tipView != null) {
            UnreadMsgUtils.show(tipView, num);
            if (mInitSetMap.contains(tempPosition)) {
                return this;
            }

            if (!getDelegate().isIconVisible()) {
                setMsgMargin(tempPosition, 2f, 2f);
            } else {
                setMsgMargin(tempPosition, 0, getDelegate().getIconGravity() == LayoutAlignment.LEFT
                        || getDelegate().getIconGravity() == LayoutAlignment.RIGHT ? 4 : 0);
            }

            mInitSetMap.put(tempPosition, true);
        }
        return this;
    }

    /**
     * 显示未读红点
     *
     * @param position 显示tab位置
     * @return CommonTabLayout
     */
    public CommonTabLayout showDot(int position) {
        int tempPosition = position;
        if (tempPosition >= mTabCount) {
            tempPosition = mTabCount - 1;
        }
        return showMsg(tempPosition, 0);
    }

    /**
     * 隐藏tab的msgview
     *
     * @param position 角标
     * @return CommonTabLayout
     */
    public CommonTabLayout hideMsg(int position) {
        int tempPosition = position;
        if (tempPosition >= mTabCount) {
            tempPosition = mTabCount - 1;
        }

        Component tabView = mTabsContainer.getComponentAt(tempPosition);
        MsgView tipView = (MsgView) tabView.findComponentById(ResourceTable.Id_rtv_msg_tip);
        if (tipView != null) {
            tipView.setVisibility(HIDE);
        }
        return this;
    }

    /**
     * 新增方法
     * 设置提示红点偏移,注意
     * 1.控件为固定高度:参照点为tab内容的右上角
     * 2.控件高度不固定(WRAP_CONTENT):参照点为tab内容的右上角,此时高度已是红点的最高显示范围,所以这时bottomPadding其实就是topPadding
     *
     * @param position      position
     * @param leftPadding   leftPadding
     * @param bottomPadding bottomPadding
     * @return CommonTabLayout
     */
    public CommonTabLayout setMsgMargin(int position, int leftPadding, int bottomPadding) {
        if (position >= mTabCount) {
            position = mTabCount - 1;
        }
        Component tabView = mTabsContainer.getComponentAt(position);
        MsgView tipView = (MsgView) tabView.findComponentById(ResourceTable.Id_rtv_msg_tip);
        if (tipView != null) {
            Text tv_tab_title = (Text) tabView.findComponentById(ResourceTable.Id_tv_tab_title);
            mTextPaint.setAntiAlias(true);
            mTextPaint.setTextSize((int) getDelegate().getTextSize());
            mTextPaint.measureText(tv_tab_title.getText());
            float textHeight = (float) ((double) mTextPaint.descent() - (double) mTextPaint.ascent());
            DependentLayout.LayoutConfig lp = (DependentLayout.LayoutConfig) tipView.getLayoutConfig();

            float iconH = getDelegate().getIconHeight();
            float margin = 0;
            if (getDelegate().isIconVisible()) {
                iconH = getIconH(position, iconH);
                margin = getDelegate().getIconMargin();
            }

            if (getDelegate().getIconGravity() == LayoutAlignment.TOP
                    || getDelegate().getIconGravity() == LayoutAlignment.BOTTOM) {
                lp.setMarginLeft(leftPadding);
                lp.setMarginTop(mHeight > 0 ?
                        (int) (mHeight - (double) textHeight - (double) iconH - (double) margin) / 2 - bottomPadding
                        : bottomPadding);
            } else {
                lp.setMarginLeft(leftPadding);
                lp.setMarginTop(mHeight > 0 ?
                        (int) (mHeight - Math.max(textHeight, (double) iconH)) / 2 - bottomPadding
                        : bottomPadding);
            }

            tipView.setLayoutConfig(lp);
        }
        return this;
    }

    private float getIconH(int position, float iconH) {
        if (iconH <= 0) {
            try {
                Element element = mContext.getResourceManager()
                        .getElement(mTabEntity.get(position).getTabSelectedIcon());
                iconH = element.getFloat();
            } catch (IOException | NotExistException | WrongTypeException e) {
                e.printStackTrace();
            }
        }
        return iconH;
    }

    /**
     * 设置msgview 的margin
     *
     * @param position      角标
     * @param leftPadding   左边距
     * @param bottomPadding 低边距
     * @return CommonTabLayout
     */
    public CommonTabLayout setMsgMargin(int position, float leftPadding, float bottomPadding) {
        return setMsgMargin(position, getDelegate().dp2px(leftPadding), getDelegate().dp2px(bottomPadding));
    }

    /**
     * 当前类只提供了少许设置未读消息属性的方法,可以通过该方法获取MsgView对象从而各种设置
     *
     * @param position position
     * @return MsgView
     */
    public MsgView getMsgView(int position) {
        if (position >= mTabCount) {
            position = mTabCount - 1;
        }
        Component tabView = mTabsContainer.getComponentAt(position);
        MsgView tipView = (MsgView) tabView.findComponentById(ResourceTable.Id_rtv_msg_tip);
        return tipView;
    }


    private Component mCenterView;

    /**
     * 设置tab 选择监听接口
     *
     * @param listener tab选择接口
     * @return CommonTabLayout
     */
    public CommonTabLayout setOnTabSelectListener(OnTabSelectListener listener) {
        this.mListener = listener;
        return this;
    }

    /**
     * 设置中间View tab必须为偶数否则抛异常
     *
     * @param centerView 中间view
     * @param width      view宽度
     * @param height     view高度
     * @param margin     centerView 左右tabView margin用于留出centerView位置
     * @param listener   centerView点击事件
     * @return CommonTabLayout
     * @throws IllegalStateException please setTabData first or the number of tabs must be even , like 4
     */
    private CommonTabLayout setCenterView(final Component centerView,
                                          final int width,
                                          final int height,
                                          int margin,
                                          final ClickedListener listener) {
        if (centerView == null) {
            return this;
        }
        if (mTabCount <= 0) {
            throw new IllegalStateException("please setTabData first!");
        }
        if (mTabCount % 2 != 0) {
            throw new IllegalStateException("the number of tabs must be even , like 4");
        }

        setCenter(centerView, width, height, margin, listener);
        return this;
    }


    private void setCenter(Component centerView, int width, int height, final int margin, ClickedListener listener) {
        if (getChildIndex(mCenterView) != -1) {
            removeComponent(mCenterView);
        }
        int tempMargin = margin > 0 ? margin : (getEstimatedWidth() / (mTabCount + 1)) / 2;
        mCenterView = centerView;
        LayoutConfig params = new LayoutConfig(width, height);
        params.alignment = LayoutAlignment.CENTER;
        addComponent(mCenterView, params);
        DirectionalLayout.LayoutConfig layoutConfig = (DirectionalLayout.LayoutConfig) mTabsContainer
                .getComponentAt(mTabCount / 2 - 1).getLayoutConfig();
        ShapeElement shapeElement = new ShapeElement();
        shapeElement.setRgbColor(RgbColor.fromArgbInt(Color.TRANSPARENT.getValue()));
        mTabsContainer.getComponentAt(mTabCount / 2 - 1).setBackground(shapeElement);
        if (layoutConfig != null) {
            layoutConfig.setMarginRight(tempMargin);
            mTabsContainer.getComponentAt(mTabCount / 2 - 1).setLayoutConfig(layoutConfig);
        }

        DirectionalLayout.LayoutConfig config = (DirectionalLayout.LayoutConfig) mTabsContainer
                .getComponentAt(mTabCount / 2).getLayoutConfig();
        if (config != null) {
            config.setMarginLeft(tempMargin);
            mTabsContainer.getComponentAt(mTabCount / 2).setLayoutConfig(config);
        }
        if (listener != null) {
            mCenterView.setClickedListener(listener);
        }
    }

    /**
     * 设置中间View tab必须为偶数否则抛异常
     *
     * @param centerView 中间View
     * @param width      宽度
     * @param height     高度
     * @param margin     边距
     * @return CommonTabLayout
     */
    public CommonTabLayout setCenterView(Component centerView, int width, int height, int margin) {
        return setCenterView(centerView, width, height, margin, null);
    }

    /**
     * 设置中间View tab必须为偶数否则抛异常
     *
     * @param centerView 中间View
     * @param width      宽度
     * @param height     高度
     * @return CommonTabLayout
     */
    public CommonTabLayout setCenterView(Component centerView, int width, int height) {
        return setCenterView(centerView, width, height, -1);
    }

    /**
     * 设置中间View tab必须为偶数否则抛异常
     *
     * @param centerView 中间View
     * @return CommonTabLayout
     */
    public CommonTabLayout setCenterView(Component centerView) {
        return setCenterView(centerView,
                DirectionalLayout.LayoutConfig.MATCH_CONTENT,
                DirectionalLayout.LayoutConfig.MATCH_CONTENT);
    }

    /**
     * 设置中间View tab必须为偶数否则抛异常
     *
     * @param centerView 中间View
     * @param width      宽度
     * @param height     高度
     * @param listener   点击事件
     * @return CommonTabLayout
     */
    public CommonTabLayout setCenterView(Component centerView, int width, int height, ClickedListener listener) {
        return setCenterView(centerView, width, height, -1, listener);
    }

    /**
     * 设置中间View tab必须为偶数否则抛异常
     *
     * @param centerView 中间View
     * @param margin     边距
     * @return CommonTabLayout
     */
    public CommonTabLayout setCenterView(Component centerView, int margin) {
        return setCenterView(centerView, margin, null);
    }

    /**
     * 设置中间View tab必须为偶数否则抛异常
     *
     * @param centerView 中间View
     * @param margin     边距
     * @param listener   点击事件
     * @return CommonTabLayout
     */
    public CommonTabLayout setCenterView(Component centerView, int margin, ClickedListener listener) {
        return setCenterView(centerView,
                DirectionalLayout.LayoutConfig.MATCH_CONTENT,
                DirectionalLayout.LayoutConfig.MATCH_CONTENT,
                margin,
                listener);
    }

    /**
     * 设置中间View tab必须为偶数否则抛异常
     *
     * @param centerView 中间View
     * @param listener   点击事件
     * @return CommonTabLayout
     */
    public CommonTabLayout setCenterView(Component centerView, ClickedListener listener) {
        return setCenterView(centerView, -1, listener);
    }

    @Override
    protected void onRtlChanged(LayoutDirection layoutDirection) {
        super.onRtlChanged(layoutDirection);
    }

    @Override
    public void onUpdate(AnimatorValue animatorValue, float value) {
        Component currentTabView = mTabsContainer.getComponentAt(this.mCurrentTab);
        float offset = (float) ((double) currentTabView.getContentPositionX() - (double) mLastP.left);
        mIndicatorRect.left = (int) ((double) mLastP.left + ((double) offset * (double) value));
        mIndicatorRect.right = mIndicatorRect.left + currentTabView.getEstimatedWidth();
        // indicatorWidth小于0时,原jpardogo's PagerSlidingTabStrip
        if (getDelegate().getIndicatorWidth() < 0) {

        } else { // indicatorWidth大于0时,圆角矩形以及三角形
            float indicatorLeft = (int) ((double) mLastP.left
                    + (double) offset * (double) value)
                    + (currentTabView.getWidth() - getDelegate().getIndicatorWidth()) / 2;
            mIndicatorRect.left = (int) indicatorLeft;
            mIndicatorRect.right = (int) (mIndicatorRect.left + getDelegate().getIndicatorWidth());
        }
        invalidate();
    }

    private final IndicatorPoint mCurrentP = new IndicatorPoint();
    private final IndicatorPoint mLastP = new IndicatorPoint();

    private static class IndicatorPoint {
        private float left;
        private float right;
    }
}
